﻿using ControlFocusWin.Entity;
using ControlFocusWin.WinUtilApi;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ControlFocusWin.Common
{
    public class KeyboardHook
    {
        private int hHook;
        public event KeyEventHandler OnKeyDownEvent;
        private Win32HookApi.HookProc KeyboardHookDelegate;

        /// <summary>
        /// 安装键盘钩子
        /// </summary>
        public void SetHook()
        {
            KeyboardHookDelegate = new Win32HookApi.HookProc(KeyboardHookProc);
            ProcessModule cModule = Process.GetCurrentProcess().MainModule;
            var mh = Win32HookApi.GetModuleHandle(cModule.ModuleName);
            hHook = Win32HookApi.SetWindowsHookEx((int)KeyEnterEnum.WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
        }

        /// <summary>
        /// 卸载键盘钩子
        /// </summary>
        public void UnHook()
        {
            Win32HookApi.UnhookWindowsHookEx(hHook);
        }

        /// <summary>
        /// 获取键盘消息
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            // 如果该消息被丢弃（nCode<0
            if (nCode >= 0)
            {
                KeyboardHookStruct KeyDataFromHook = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

                int keyDataValue = KeyDataFromHook.vkCode;
                Keys keyData = (Keys)KeyDataFromHook.vkCode;

                //WM_KEYDOWN和WM_SYSKEYDOWN消息，将会引发OnKeyDownEvent事件
                if (OnKeyDownEvent != null && (wParam == (int)KeyEnterEnum.WM_KEYDOWN || wParam == (int)KeyEnterEnum.WM_SYSKEYDOWN))
                {
                    // 此处触发键盘按下事件
                    // keyData为按下键盘的值,对应 虚拟码
                    KeyEventArgs e = new KeyEventArgs(keyData);
                    OnKeyDownEvent(this, e);
                }
            }
            return Win32HookApi.CallNextHookEx(hHook, nCode, wParam, lParam);
        }

    }
}
